//---------------------------------------------------------------------------------
// Copyright (c) 2011, Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//---------------------------------------------------------------------------------

namespace Microsoft.Samples.ServiceBus.SilverlightChat.Models.Commands
{
    using System;
    using System.Windows.Input;
    using Microsoft.Samples.ServiceBus.Messaging;
    using Microsoft.Samples.ServiceBus.SilverlightChat.Models.ViewModels;

    /// <summary>
    /// Encapsulates a command to send a brokered message to a topic. The text of the message is
    /// sent in the message body and the name of the user who sent it is sent as a Message Property
    /// </summary>
    public class SendMessageCommand : ICommand
    {
        private readonly ChatWindowViewModel viewModel;

        public SendMessageCommand(ChatWindowViewModel viewModel)
        {
            if (viewModel == null)
            {
                throw new ArgumentNullException("viewModel");
            }

            this.viewModel = viewModel;
        }

        public event EventHandler CanExecuteChanged;

        public ChatWindowViewModel ViewModel
        {
            get { return this.viewModel; }
        }

        public bool CanExecute(object parameter)
        {
            return this.ViewModel.CurrentTopic != null;
        }

        public void Execute(object parameter)
        {
            if (this.CanExecute(parameter))
            {
                // Gets a Brokered Message containing the current user's name as a message property
                // and the entered text as the body.
                var message = this.ViewModel.CurrentMessage.CreateBrokeredMessage();
                var topicClient = this.ViewModel.CurrentTopic.TopicClient;

                topicClient.BeginSend(message, this.OnSendMessageCompleted, topicClient);
            }
        }

        public void OnSendMessageCompleted(IAsyncResult result)
        {
            // Retrieve the sender used to begin this async request
            var topicClient = (TopicClient)result.AsyncState;
            try
            {
                // End the send request - if the message was not sent, an exception will be thrown
                // here
                topicClient.EndSend(result);

                // Update the UI, clearing the value of the previously entered message and waiting 
                // for another
                this.ViewModel.Window.Dispatcher.BeginInvoke(() =>
                {
                    this.ViewModel.CurrentMessage.Value = string.Empty;
                });
            }
            catch (Exception e)
            {
                App.ShowError(e);
            }
        }

        protected void OnCanExecuteChanged(object sender, EventArgs e)
        {
            if (this.CanExecuteChanged != null)
            {
                this.CanExecuteChanged(sender, e);
            }
        }
    }
}
